using System;
using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;

namespace RaisingStudio.SmallBasicCompiler.Expressions
{
	[Serializable]
	public class ArrayExpression : Expression
	{
		public Expression LeftHand
		{
			get;
			set;
		}
		public Expression Indexer
		{
			get;
			set;
		}
		public override void AddSymbols(SymbolTable symbolTable)
		{
			if (this.LeftHand != null)
			{
				this.LeftHand.AddSymbols(symbolTable);
			}
			if (this.Indexer != null)
			{
				this.Indexer.AddSymbols(symbolTable);
			}
		}
		public void AddSymbolInitialization(SymbolTable symbolTable)
		{
			ArrayExpression arrayExpression = this.LeftHand as ArrayExpression;
			IdentifierExpression identifierExpression = this.LeftHand as IdentifierExpression;
			if (arrayExpression != null)
			{
				arrayExpression.AddSymbolInitialization(symbolTable);
				return;
			}
			if (identifierExpression != null)
			{
				identifierExpression.AddSymbolInitialization(symbolTable);
			}
		}
		public override void EmitIL(CodeGenScope scope)
		{
			this.LeftHand.EmitIL(scope);
			this.Indexer.EmitIL(scope);
			scope.ILGenerator.EmitCall(OpCodes.Call, scope.TypeInfoBag.GetArrayValue, null);
		}
		public void EmitILForSetter(CodeGenScope scope)
		{
			this.LeftHand.EmitIL(scope);
			this.Indexer.EmitIL(scope);
			scope.ILGenerator.EmitCall(OpCodes.Call, scope.TypeInfoBag.SetArrayValue, null);
			ArrayExpression arrayExpression = this.LeftHand as ArrayExpression;
			IdentifierExpression identifierExpression = this.LeftHand as IdentifierExpression;
			if (arrayExpression != null)
			{
				arrayExpression.EmitILForSetter(scope);
				return;
			}
			if (identifierExpression != null)
			{
				FieldInfo field = scope.Fields[identifierExpression.Identifier.NormalizedText];
				scope.ILGenerator.Emit(OpCodes.Stsfld, field);
			}
		}
		public override string ToString()
		{
			return string.Format(CultureInfo.CurrentUICulture, "{0}[{1}]", new object[]
			{
				this.LeftHand.ToString(), 
				this.Indexer
			});
		}
	}
}
